import { ComponentResolver, SideEffectsInfo } from 'unplugin-vue-components'

/**
 * 生成 unplugin-vue-components 组件库组件自动按需导入的解析器
 *
 * @param {string} componentNameStartsWith 组件库组件名称前缀，组件的名称以什么开头，指定的组件名称前缀开头的组件才会被解析器解析
 * @param {string} from 需要自动按需导入的组件的来源组件库的名称，即要从那个组件库中自动按需导入组件
 * @param {(componentName: string) => SideEffectsInfo} sideEffects 跟随组件一同导入的附加内容，如 CSS 文件，通过传入一个函数来动态
 * 生成如何导入需要跟随组件一同导入的附加内容，会向传递进来的函数传递的参数：
 * - componentName 需要自动按需导入的组件的名称
 * @returns {() => ComponentResolver} unplugin-vue-components 组件库组件自动按需导入的解析器
 */
export const genComponentResolver = (
  componentNameStartsWith: string,
  from: string,
  sideEffects: (componentName: string) => SideEffectsInfo
): (() => ComponentResolver) => {
  return (): ComponentResolver => {
    return {
      // 指定该解析器对什么类型进行解析
      // 这里指定对组件类型进行解析，然后根据组件名称自动按需导入组件
      type: 'component',
      // 解析器处理函数
      // 根据组件名称自动按需导入组件
      resolve: (name: string) => {
        // 判断解析的组件名称是不是当前组件库的
        if (name.startsWith(componentNameStartsWith)) {
          return {
            // 要导入的组件名称
            name,
            // 从哪里导入
            from,
            // 根据组件名称自动按需导入组件时，需要一同导入的附加内容
            // 由于组件的样式是打包到了单独的样式文件中，所以还需在这里指定导入组件的样式文件
            sideEffects: sideEffects(name)
          }
        }
      }
    }
  }
}

export type GenComponentResolverType = typeof genComponentResolver
